package models;


public class AllocationStrategy {
	private SLA sla1;
	private PerformanceModel pModel1;
	private SLA sla2;
	private PerformanceModel pModel2;

	public AllocationStrategy(SLA sla1, PerformanceModel pModel1, SLA sla2,	PerformanceModel pModel2){
		this.sla1 = sla1;
		this.pModel1 = pModel1;
		this.sla2 = sla2;
		this.pModel2 = pModel2;
	}
	
	public double gSla1(int a, int b, double h, boolean all){
		
		double res = 0;
		double x = 0;
		double y = 0;		
		double area = 0;
		
		area = (getBestM1(a, all)-getBestM1(b, all))/2;
				
		for(double i=a; i<=b; i+=h){	
			x = a + i*h;
			y = getBestM1(x, all); 
			area = area + y;
		}
		res = area*h;
		return res;			
	}
	
	
	public double gSla2(int a, int b, double h, boolean all){
		
		double res = 0;
		double x = 0;
		double y = 0;		
		double area = 0;
			
		area = (getBestM2(a, all)-getBestM2(b, all))/2;
		
		for(double i=a; i<=b; i+=h){	
			x = a + i*h;
			y = getBestM2(x, all);
			area = area + y;	
		}
			
		res = area*h;
		return res;			
	}

	
	public SLA getSla1() {
		return sla1;
	}


	public void setSla1(SLA sla1) {
		this.sla1 = sla1;
	}


	public PerformanceModel getpModel1() {
		return pModel1;
	}


	public void setpModel1(PerformanceModel pModel1) {
		this.pModel1 = pModel1;
	}


	public SLA getSla2() {
		return sla2;
	}


	public void setSla2(SLA sla2) {
		this.sla2 = sla2;
	}


	public PerformanceModel getpModel2() {
		return pModel2;
	}


	public void setpModel2(PerformanceModel pModel2) {
		this.pModel2 = pModel2;
	}
	
	//allocationStrategy true per DA, false per SA
	public int getBestM1(double l, boolean allocationStrategy){
		
		double x = sla1.getX();
		double y = sla1.getY();
		
		pModel1.setLambda(l);
		
		if(allocationStrategy)
			pModel1.setP((pModel1.getLambda())/pModel1.getMu());
		else
			pModel1.setP((pModel1.getLambda() + pModel2.getLambda())/pModel1.getMu());

		int m=1;//(int)Math.floor(pModel1.getP() +1);
		
		pModel1.setM(m);
		while(pModel1.calculateCDF(x) < y){
			m++;
			pModel1.setM(m);
			System.out.println("m = " + m);
		}		
		return m;
	}

	public int getBestM2(double l, boolean allocationStrategy){
		double x = sla2.getX();
		double y = sla2.getY();
		
		pModel2.setLambda(l);
		
		if(allocationStrategy)
			pModel2.setP((pModel2.getLambda())/pModel2.getMu());
		else
			pModel2.setP((pModel1.getLambda() + pModel2.getLambda())/pModel2.getMu());
		
		int m = (int)Math.floor(pModel2.getP() +1);
		pModel2.setM(m);
		
		while(pModel2.calculateCDF(x) < y){
			m++;
			pModel2.setM(m);
			System.out.println("m = " + m);
		}		
		return m;
	}
	
	public static void main(String[] args){
		
		SLA sla1=new SLA(5, 0.85);
		SLA sla2=new SLA(3, 0.95);
		PerformanceModel pm1 = new PerformanceModel(0.6, 3.6);
		PerformanceModel pm2 = new PerformanceModel(3, 3.6);

		AllocationStrategy as = new AllocationStrategy(sla1, pm1, sla2, pm2);

		double gslas1 = as.gSla1(0, 40, 0.1, false);
		double gslas2 = as.gSla2(0, 40, 0.1, false);
		double ds = Math.abs(gslas1-gslas2);
	
		double gslad1 = as.gSla1(0, 40, 0.1, true);
		double gslad2 = as.gSla2(0, 40, 0.1, true);
		double dd = Math.abs(gslad1-gslad2);

		System.out.println("gSlaSA1: " + gslas1);
		System.out.println("gSlaSA2: " + gslas2);
		System.out.println("Difference_SA: " + ds);
		
		System.out.println("gSlaDA1: " + gslad1);
		System.out.println("gSlaDA2: " + gslad2);
		System.out.println("Difference_DA: " + dd);		
	}	

}
